package com.gujianjian.testjwt.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gujianjian.testjwt.exceptions.TokenUnavailable;

import java.util.Calendar;
import java.util.Date;

/**
 * @author 顾小健
 * @create: 2021-12-12
 */

public class JwtUtils {

    private static final String KEY = "HELLO JOY";

    /**
     * 签发对象：这个用户的id
     * 签发时间：现在
     * 有效时间：30分钟
     * 载荷内容：暂时设计为：这个人的名字，这个人的昵称
     * 加密密钥：这个人的id加上一串字符串
     */
    public static String createToken(String audience, String realname, String username) {

        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, 2);
        Date expiresDate = nowTime.getTime();

        return JWT.create().withAudience(audience)   //签发对象
                .withIssuedAt(new Date())    //发行时间
                .withExpiresAt(expiresDate)  //有效时间
                .withClaim("username", username)    //载荷 用户名
                .withClaim("realname", realname)    //载荷 昵称
                .sign(Algorithm.HMAC256(audience + KEY));   //加密
    }

    /**
     * 检验合法性
     * @param token
     * @param audience 签发对象，创建token时传入的
     * @throws TokenUnavailable
     */
    public static void verifyToken(String token, String audience) throws TokenUnavailable {
        DecodedJWT jwt = null;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(audience + KEY)).build();
            jwt = verifier.verify(token);
        } catch (Exception e) {
            //效验失败
            //这里抛出的异常是我自定义的一个异常，你也可以写成别的
            throw new TokenUnavailable();
        }
    }

    /**
     * 获取签发对象
     */
    public static String getAudience(String token) throws TokenUnavailable {
        String audience = null;
        try {
            audience = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            //这里是token解析失败
            throw new TokenUnavailable();
        }
        return audience;
    }


    /**
     *  通过载荷名字获取载荷的值
     * @param token jwt token
     * @param name 载荷名字
     * @return
     */
    public static Claim getClaimByName(String token, String name) {
        return JWT.decode(token).getClaim(name);
    }
}

